home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / gnuplot / internal.c < prev    next >
C/C++ Source or Header  |  1993-09-15  |  17KB  |  893 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: internal.c%v 3.50.1.8 1993/07/27 05:37:15 woo Exp $";
  3. #endif
  4.  
  5.  
  6. /* GNUPLOT - internal.c */
  7. /*
  8.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  9.  *
  10.  * Permission to use, copy, and distribute this software and its
  11.  * documentation for any purpose with or without fee is hereby granted, 
  12.  * provided that the above copyright notice appear in all copies and 
  13.  * that both that copyright notice and this permission notice appear 
  14.  * in supporting documentation.
  15.  *
  16.  * Permission to modify the software is granted, but not the right to
  17.  * distribute the modified code.  Modifications are to be distributed 
  18.  * as patches to released version.
  19.  *  
  20.  * This software is provided "as is" without express or implied warranty.
  21.  * 
  22.  *
  23.  * AUTHORS
  24.  * 
  25.  *   Original Software:
  26.  *     Thomas Williams,  Colin Kelley.
  27.  * 
  28.  *   Gnuplot 2.0 additions:
  29.  *       Russell Lang, Dave Kotz, John Campbell.
  30.  *
  31.  *   Gnuplot 3.0 additions:
  32.  *       Gershon Elber and many others.
  33.  * 
  34.  */
  35.  
  36. #include <math.h>
  37. #include <stdio.h>
  38. #include "plot.h"
  39.  
  40. TBOOLEAN undefined;
  41.  
  42. #ifndef AMIGA_SC_6_1
  43. char *strcpy();
  44. #endif /* !AMIGA_SC_6_1 */
  45.  
  46. struct value *pop(), *Gcomplex(), *Ginteger();
  47. double magnitude(), angle(), real();
  48.  
  49. struct value stack[STACK_DEPTH];
  50.  
  51. int s_p = -1;   /* stack pointer */
  52.  
  53.  
  54. /*
  55.  * System V and MSC 4.0 call this when they wants to print an error message.
  56.  * Don't!
  57.  */
  58. #ifndef _CRAY
  59. #if defined(MSDOS) || defined(DOS386)
  60. #ifdef __TURBOC__
  61. int matherr()    /* Turbo C */
  62. #else
  63. int matherr(x)    /* MSC 5.1 */
  64. struct exception *x;
  65. #endif /* TURBOC */
  66. #else /* not MSDOS */
  67. #ifdef apollo
  68. int matherr(struct exception *x)    /* apollo */
  69. #else /* apollo */
  70. #if defined(AMIGA_SC_6_1)||defined(ATARI)&&defined(__GNUC__)||defined(__hpux__)||defined(PLOSS) ||defined(SOLARIS)
  71. int matherr(x)
  72. struct exception *x;
  73. #else    /* Most everyone else (not apollo). */
  74. int matherr()
  75. #endif /* AMIGA_SC_6_1 || GCC_ST */
  76. #endif /* apollo */
  77. #endif /* MSDOS */
  78. {
  79.     return (undefined = TRUE);        /* don't print error message */
  80. }
  81. #endif /* not _CRAY */
  82.  
  83.  
  84. reset_stack()
  85. {
  86.     s_p = -1;
  87. }
  88.  
  89.  
  90. check_stack()    /* make sure stack's empty */
  91. {
  92.     if (s_p != -1)
  93.         fprintf(stderr,"\nwarning:  internal error--stack not empty!\n");
  94. }
  95.  
  96.  
  97. struct value *pop(x)
  98. struct value *x;
  99. {
  100.     if (s_p  < 0 )
  101.         int_error("stack underflow",NO_CARET);
  102.     *x = stack[s_p--];
  103.     return(x);
  104. }
  105.  
  106.  
  107. push(x)
  108. struct value *x;
  109. {
  110.     if (s_p == STACK_DEPTH - 1)
  111.         int_error("stack overflow",NO_CARET);
  112.     stack[++s_p] = *x;
  113. }
  114.  
  115.  
  116. #define ERR_VAR "undefined variable: "
  117.  
  118. f_push(x)
  119. union argument *x;        /* contains pointer to value to push; */
  120. {
  121. static char err_str[sizeof(ERR_VAR) + MAX_ID_LEN] = ERR_VAR;
  122. struct udvt_entry *udv;
  123.  
  124.     udv = x->udv_arg;
  125.     if (udv->udv_undef) {     /* undefined */
  126.         (void) strcpy(&err_str[sizeof(ERR_VAR) - 1], udv->udv_name);
  127.         int_error(err_str,NO_CARET);
  128.     }
  129.     push(&(udv->udv_value));
  130. }
  131.  
  132.  
  133. f_pushc(x)
  134. union argument *x;
  135. {
  136.     push(&(x->v_arg));
  137. }
  138.  
  139.  
  140. f_pushd1(x)
  141. union argument *x;
  142. {
  143.     push(&(x->udf_arg->dummy_values[0]));
  144. }
  145.  
  146.  
  147. f_pushd2(x)
  148. union argument *x;
  149. {
  150.     push(&(x->udf_arg->dummy_values[1]));
  151. }
  152.  
  153.  
  154. f_pushd(x)
  155. union argument *x;
  156. {
  157. struct value param;
  158.     (void) pop(¶m);
  159.     push(&(x->udf_arg->dummy_values[param.v.int_val]));
  160. }
  161.  
  162.  
  163. #define ERR_FUN "undefined function: "
  164.  
  165. f_call(x)  /* execute a udf */
  166. union argument *x;
  167. {
  168. static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  169. register struct udft_entry *udf;
  170. struct value save_dummy;
  171.  
  172.     udf = x->udf_arg;
  173.     if (!udf->at) { /* undefined */
  174.         (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  175.                 udf->udf_name);
  176.         int_error(err_str,NO_CARET);
  177.     }
  178.     save_dummy = udf->dummy_values[0];
  179.     (void) pop(&(udf->dummy_values[0]));
  180.  
  181.     execute_at(udf->at);
  182.     udf->dummy_values[0] = save_dummy;
  183. }
  184.  
  185.  
  186. f_calln(x)  /* execute a udf of n variables */
  187. union argument *x;
  188. {
  189. static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  190. register struct udft_entry *udf;
  191. struct value save_dummy[MAX_NUM_VAR];
  192.  
  193.     int i;
  194.     int num_pop;
  195.     struct value num_params;
  196.  
  197.     udf = x->udf_arg;
  198.     if (!udf->at) { /* undefined */
  199.         (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  200.                 udf->udf_name);
  201.         int_error(err_str,NO_CARET);
  202.     }
  203.     for(i=0; i<MAX_NUM_VAR; i++) 
  204.         save_dummy[i] = udf->dummy_values[i];
  205.  
  206.     /* if there are more parameters than the function is expecting */
  207.     /* simply ignore the excess */
  208.     (void) pop(&num_params);
  209.  
  210.     if(num_params.v.int_val > MAX_NUM_VAR) {
  211.         /* pop the dummies that there is no room for */
  212.         num_pop = num_params.v.int_val - MAX_NUM_VAR;
  213.         for(i=0; i< num_pop; i++)
  214.             (void) pop(&(udf->dummy_values[i]));
  215.  
  216.         num_pop = MAX_NUM_VAR;
  217.     } else {
  218.         num_pop = num_params.v.int_val;
  219.     }
  220.  
  221.     /* pop parameters we can use */
  222.     for(i=num_pop-1; i>=0; i--)
  223.         (void) pop(&(udf->dummy_values[i]));
  224.  
  225.     execute_at(udf->at);
  226.     for(i=0; i<MAX_NUM_VAR; i++) 
  227.         udf->dummy_values[i] = save_dummy[i];
  228. }
  229.  
  230.  
  231. static int_check(v)
  232. struct value *v;
  233. {
  234.     if (v->type != INTGR)
  235.         int_error("non-integer passed to boolean operator",NO_CARET);
  236. }
  237.  
  238.  
  239. f_lnot()
  240. {
  241. struct value a;
  242.     int_check(pop(&a));
  243.     push(Ginteger(&a,!a.v.int_val) );
  244. }
  245.  
  246.  
  247. f_bnot()
  248. {
  249. struct value a;
  250.     int_check(pop(&a));
  251.     push( Ginteger(&a,~a.v.int_val) );
  252. }
  253.  
  254.  
  255. f_bool()
  256. {            /* converts top-of-stack to boolean */
  257.     int_check(&top_of_stack);
  258.     top_of_stack.v.int_val = !!top_of_stack.v.int_val;
  259. }
  260.  
  261.  
  262. f_lor()
  263. {
  264. struct value a,b;
  265.     int_check(pop(&b));
  266.     int_check(pop(&a));
  267.     push( Ginteger(&a,a.v.int_val || b.v.int_val) );
  268. }
  269.  
  270. f_land()
  271. {
  272. struct value a,b;
  273.     int_check(pop(&b));
  274.     int_check(pop(&a));
  275.     push( Ginteger(&a,a.v.int_val && b.v.int_val) );
  276. }
  277.  
  278.  
  279. f_bor()
  280. {
  281. struct value a,b;
  282.     int_check(pop(&b));
  283.     int_check(pop(&a));
  284.     push( Ginteger(&a,a.v.int_val | b.v.int_val) );
  285. }
  286.  
  287.  
  288. f_xor()
  289. {
  290. struct value a,b;
  291.     int_check(pop(&b));
  292.     int_check(pop(&a));
  293.     push( Ginteger(&a,a.v.int_val ^ b.v.int_val) );
  294. }
  295.  
  296.  
  297. f_band()
  298. {
  299. struct value a,b;
  300.     int_check(pop(&b));
  301.     int_check(pop(&a));
  302.     push( Ginteger(&a,a.v.int_val & b.v.int_val) );
  303. }
  304.  
  305.  
  306. f_uminus()
  307. {
  308. struct value a;
  309.     (void) pop(&a);
  310.     switch(a.type) {
  311.         case INTGR:
  312.             a.v.int_val = -a.v.int_val;
  313.             break;
  314.         case CMPLX:
  315.             a.v.cmplx_val.real =
  316.                 -a.v.cmplx_val.real;
  317.             a.v.cmplx_val.imag =
  318.                 -a.v.cmplx_val.imag;
  319.     }
  320.     push(&a);
  321. }
  322.  
  323.  
  324. f_eq() /* note: floating point equality is rare because of roundoff error! */
  325. {
  326. struct value a, b;
  327.     register int result;
  328.     (void) pop(&b);
  329.     (void) pop(&a);
  330.     switch(a.type) {
  331.         case INTGR:
  332.             switch (b.type) {
  333.                 case INTGR:
  334.                     result = (a.v.int_val ==
  335.                         b.v.int_val);
  336.                     break;
  337.                 case CMPLX:
  338.                     result = (a.v.int_val ==
  339.                         b.v.cmplx_val.real &&
  340.                        b.v.cmplx_val.imag == 0.0);
  341.             }
  342.             break;
  343.         case CMPLX:
  344.             switch (b.type) {
  345.                 case INTGR:
  346.                     result = (b.v.int_val == a.v.cmplx_val.real &&
  347.                        a.v.cmplx_val.imag == 0.0);
  348.                     break;
  349.                 case CMPLX:
  350.                     result = (a.v.cmplx_val.real==
  351.                         b.v.cmplx_val.real &&
  352.                         a.v.cmplx_val.imag==
  353.                         b.v.cmplx_val.imag);
  354.             }
  355.     }
  356.     push(Ginteger(&a,result));
  357. }
  358.  
  359.  
  360. f_ne()
  361. {
  362. struct value a, b;
  363.     register int result;
  364.     (void) pop(&b);
  365.     (void) pop(&a);
  366.     switch(a.type) {
  367.         case INTGR:
  368.             switch (b.type) {
  369.                 case INTGR:
  370.                     result = (a.v.int_val !=
  371.                         b.v.int_val);
  372.                     break;
  373.                 case CMPLX:
  374.                     result = (a.v.int_val !=
  375.                         b.v.cmplx_val.real ||
  376.                        b.v.cmplx_val.imag != 0.0);
  377.             }
  378.             break;
  379.         case CMPLX:
  380.             switch (b.type) {
  381.                 case INTGR:
  382.                     result = (b.v.int_val !=
  383.                         a.v.cmplx_val.real ||
  384.                        a.v.cmplx_val.imag != 0.0);
  385.                     break;
  386.                 case CMPLX:
  387.                     result = (a.v.cmplx_val.real !=
  388.                         b.v.cmplx_val.real ||
  389.                         a.v.cmplx_val.imag !=
  390.                         b.v.cmplx_val.imag);
  391.             }
  392.     }
  393.     push(Ginteger(&a,result));
  394. }
  395.  
  396.  
  397. f_gt()
  398. {
  399. struct value a, b;
  400.     register int result;
  401.     (void) pop(&b);
  402.     (void) pop(&a);
  403.     switch(a.type) {
  404.         case INTGR:
  405.             switch (b.type) {
  406.                 case INTGR:
  407.                     result = (a.v.int_val >
  408.                         b.v.int_val);
  409.                     break;
  410.                 case CMPLX:
  411.                     result = (a.v.int_val >
  412.                         b.v.cmplx_val.real);
  413.             }
  414.             break;
  415.         case CMPLX:
  416.             switch (b.type) {
  417.                 case INTGR:
  418.                     result = (a.v.cmplx_val.real >
  419.                         b.v.int_val);
  420.                     break;
  421.                 case CMPLX:
  422.                     result = (a.v.cmplx_val.real >
  423.                         b.v.cmplx_val.real);
  424.             }
  425.     }
  426.     push(Ginteger(&a,result));
  427. }
  428.  
  429.  
  430. f_lt()
  431. {
  432. struct value a, b;
  433.     register int result;
  434.     (void) pop(&b);
  435.     (void) pop(&a);
  436.     switch(a.type) {
  437.         case INTGR:
  438.             switch (b.type) {
  439.                 case INTGR:
  440.                     result = (a.v.int_val <
  441.                         b.v.int_val);
  442.                     break;
  443.                 case CMPLX:
  444.                     result = (a.v.int_val <
  445.                         b.v.cmplx_val.real);
  446.             }
  447.             break;
  448.         case CMPLX:
  449.             switch (b.type) {
  450.                 case INTGR:
  451.                     result = (a.v.cmplx_val.real <
  452.                         b.v.int_val);
  453.                     break;
  454.                 case CMPLX:
  455.                     result = (a.v.cmplx_val.real <
  456.                         b.v.cmplx_val.real);
  457.             }
  458.     }
  459.     push(Ginteger(&a,result));
  460. }
  461.  
  462.  
  463. f_ge()
  464. {
  465. struct value a, b;
  466.     register int result;
  467.     (void) pop(&b);
  468.     (void) pop(&a);
  469.     switch(a.type) {
  470.         case INTGR:
  471.             switch (b.type) {
  472.                 case INTGR:
  473.                     result = (a.v.int_val >=
  474.                         b.v.int_val);
  475.                     break;
  476.                 case CMPLX:
  477.                     result = (a.v.int_val >=
  478.                         b.v.cmplx_val.real);
  479.             }
  480.             break;
  481.         case CMPLX:
  482.             switch (b.type) {
  483.                 case INTGR:
  484.                     result = (a.v.cmplx_val.real >=
  485.                         b.v.int_val);
  486.                     break;
  487.                 case CMPLX:
  488.                     result = (a.v.cmplx_val.real >=
  489.                         b.v.cmplx_val.real);
  490.             }
  491.     }
  492.     push(Ginteger(&a,result));
  493. }
  494.  
  495.  
  496. f_le()
  497. {
  498. struct value a, b;
  499.     register int result;
  500.     (void) pop(&b);
  501.     (void) pop(&a);
  502.     switch(a.type) {
  503.         case INTGR:
  504.             switch (b.type) {
  505.                 case INTGR:
  506.                     result = (a.v.int_val <=
  507.                         b.v.int_val);
  508.                     break;
  509.                 case CMPLX:
  510.                     result = (a.v.int_val <=
  511.                         b.v.cmplx_val.real);
  512.             }
  513.             break;
  514.         case CMPLX:
  515.             switch (b.type) {
  516.                 case INTGR:
  517.                     result = (a.v.cmplx_val.real <=
  518.                         b.v.int_val);
  519.                     break;
  520.                 case CMPLX:
  521.                     result = (a.v.cmplx_val.real <=
  522.                         b.v.cmplx_val.real);
  523.             }
  524.     }
  525.     push(Ginteger(&a,result));
  526. }
  527.  
  528.  
  529. f_plus()
  530. {
  531. struct value a, b, result;
  532.     (void) pop(&b);
  533.     (void) pop(&a);
  534.     switch(a.type) {
  535.         case INTGR:
  536.             switch (b.type) {
  537.                 case INTGR:
  538.                     (void) Ginteger(&result,a.v.int_val +
  539.                         b.v.int_val);
  540.                     break;
  541.                 case CMPLX:
  542.                     (void) Gcomplex(&result,a.v.int_val +
  543.                         b.v.cmplx_val.real,
  544.                        b.v.cmplx_val.imag);
  545.             }
  546.             break;
  547.         case CMPLX:
  548.             switch (b.type) {
  549.                 case INTGR:
  550.                     (void) Gcomplex(&result,b.v.int_val +
  551.                         a.v.cmplx_val.real,
  552.                        a.v.cmplx_val.imag);
  553.                     break;
  554.                 case CMPLX:
  555.                     (void) Gcomplex(&result,a.v.cmplx_val.real+
  556.                         b.v.cmplx_val.real,
  557.                         a.v.cmplx_val.imag+
  558.                         b.v.cmplx_val.imag);
  559.             }
  560.     }
  561.     push(&result);
  562. }
  563.  
  564.  
  565. f_minus()
  566. {
  567. struct value a, b, result;
  568.     (void) pop(&b);
  569.     (void) pop(&a);        /* now do a - b */
  570.     switch(a.type) {
  571.         case INTGR:
  572.             switch (b.type) {
  573.                 case INTGR:
  574.                     (void) Ginteger(&result,a.v.int_val -
  575.                         b.v.int_val);
  576.                     break;
  577.                 case CMPLX:
  578.                     (void) Gcomplex(&result,a.v.int_val -
  579.                         b.v.cmplx_val.real,
  580.                        -b.v.cmplx_val.imag);
  581.             }
  582.             break;
  583.         case CMPLX:
  584.             switch (b.type) {
  585.                 case INTGR:
  586.                     (void) Gcomplex(&result,a.v.cmplx_val.real -
  587.                         b.v.int_val,
  588.                         a.v.cmplx_val.imag);
  589.                     break;
  590.                 case CMPLX:
  591.                     (void) Gcomplex(&result,a.v.cmplx_val.real-
  592.                         b.v.cmplx_val.real,
  593.                         a.v.cmplx_val.imag-
  594.                         b.v.cmplx_val.imag);
  595.             }
  596.     }
  597.     push(&result);
  598. }
  599.  
  600.  
  601. f_mult()
  602. {
  603. struct value a, b, result;
  604.     (void) pop(&b);
  605.     (void) pop(&a);    /* now do a*b */
  606.  
  607.     switch(a.type) {
  608.         case INTGR:
  609.             switch (b.type) {
  610.                 case INTGR:
  611.                     (void) Ginteger(&result,a.v.int_val *
  612.                         b.v.int_val);
  613.                     break;
  614.                 case CMPLX:
  615.                     (void) Gcomplex(&result,a.v.int_val *
  616.                         b.v.cmplx_val.real,
  617.                         a.v.int_val *
  618.                         b.v.cmplx_val.imag);
  619.             }
  620.             break;
  621.         case CMPLX:
  622.             switch (b.type) {
  623.                 case INTGR:
  624.                     (void) Gcomplex(&result,b.v.int_val *
  625.                         a.v.cmplx_val.real,
  626.                         b.v.int_val *
  627.                         a.v.cmplx_val.imag);
  628.                     break;
  629.                 case CMPLX:
  630.                     (void) Gcomplex(&result,a.v.cmplx_val.real*
  631.                         b.v.cmplx_val.real-
  632.                         a.v.cmplx_val.imag*
  633.                         b.v.cmplx_val.imag,
  634.                         a.v.cmplx_val.real*
  635.                         b.v.cmplx_val.imag+
  636.                         a.v.cmplx_val.imag*
  637.                         b.v.cmplx_val.real);
  638.             }
  639.     }
  640.     push(&result);
  641. }
  642.  
  643.  
  644. f_div()
  645. {
  646. struct value a, b, result;
  647. register double square;
  648.     (void) pop(&b);
  649.     (void) pop(&a);    /* now do a/b */
  650.  
  651.     switch(a.type) {
  652.         case INTGR:
  653.             switch (b.type) {
  654.                 case INTGR:
  655.                     if (b.v.int_val)
  656.                       (void) Ginteger(&result,a.v.int_val /
  657.                         b.v.int_val);
  658.                     else {
  659.                       (void) Ginteger(&result,0);
  660.                       undefined = TRUE;
  661.                     }
  662.                     break;
  663.                 case CMPLX:
  664.                     square = b.v.cmplx_val.real*
  665.                         b.v.cmplx_val.real +
  666.                         b.v.cmplx_val.imag*
  667.                         b.v.cmplx_val.imag;
  668.                     if (square)
  669.                         (void) Gcomplex(&result,a.v.int_val*
  670.                         b.v.cmplx_val.real/square,
  671.                         -a.v.int_val*
  672.                         b.v.cmplx_val.imag/square);
  673.                     else {
  674.                         (void) Gcomplex(&result,0.0,0.0);
  675.                         undefined = TRUE;
  676.                     }
  677.             }
  678.             break;
  679.         case CMPLX:
  680.             switch (b.type) {
  681.                 case INTGR:
  682.                     if (b.v.int_val)
  683.                       
  684.                       (void) Gcomplex(&result,a.v.cmplx_val.real/
  685.                         b.v.int_val,
  686.                         a.v.cmplx_val.imag/
  687.                         b.v.int_val);
  688.                     else {
  689.                         (void) Gcomplex(&result,0.0,0.0);
  690.                         undefined = TRUE;
  691.                     }
  692.                     break;
  693.                 case CMPLX:
  694.                     square = b.v.cmplx_val.real*
  695.                         b.v.cmplx_val.real +
  696.                         b.v.cmplx_val.imag*
  697.                         b.v.cmplx_val.imag;
  698.                     if (square)
  699.                     (void) Gcomplex(&result,(a.v.cmplx_val.real*
  700.                         b.v.cmplx_val.real+
  701.                         a.v.cmplx_val.imag*
  702.                         b.v.cmplx_val.imag)/square,
  703.                         (a.v.cmplx_val.imag*
  704.                         b.v.cmplx_val.real-
  705.                         a.v.cmplx_val.real*
  706.                         b.v.cmplx_val.imag)/
  707.                             square);
  708.                     else {
  709.                         (void) Gcomplex(&result,0.0,0.0);
  710.                         undefined = TRUE;
  711.                     }
  712.             }
  713.     }
  714.     push(&result);
  715. }
  716.  
  717.  
  718. f_mod()
  719. {
  720. struct value a, b;
  721.     (void) pop(&b);
  722.     (void) pop(&a);    /* now do a%b */
  723.  
  724.     if (a.type != INTGR || b.type != INTGR)
  725.         int_error("can only mod ints",NO_CARET);
  726.     if (b.v.int_val)
  727.         push(Ginteger(&a,a.v.int_val % b.v.int_val));
  728.     else {
  729.         push(Ginteger(&a,0));
  730.         undefined = TRUE;
  731.     }
  732. }
  733.  
  734.  
  735. f_power()
  736. {
  737. struct value a, b, result;
  738. register int i, t, count;
  739. register double mag, ang;
  740.     (void) pop(&b);
  741.     (void) pop(&a);    /* now find a**b */
  742.  
  743.     switch(a.type) {
  744.         case INTGR:
  745.             switch (b.type) {
  746.                 case INTGR:
  747.                     count = abs(b.v.int_val);
  748.                     t = 1;
  749.                     for(i = 0; i < count; i++)
  750.                         t *= a.v.int_val;
  751.                     if (b.v.int_val >= 0)
  752.                         (void) Ginteger(&result,t);
  753.                     else
  754.                       if (t != 0)
  755.                         (void) Gcomplex(&result,1.0/t,0.0);
  756.                       else {
  757.                          undefined = TRUE;
  758.                          (void) Gcomplex(&result, 0.0, 0.0);
  759.                       }
  760.                     break;
  761.                 case CMPLX:
  762.                     mag =
  763.                       pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  764.                     if (b.v.cmplx_val.real < 0.0)
  765.                       if (mag != 0.0)
  766.                         mag = 1.0/mag;
  767.                       else 
  768.                         undefined = TRUE;
  769.                     mag *= exp(-b.v.cmplx_val.imag*angle(&a));
  770.                     ang = b.v.cmplx_val.real*angle(&a) +
  771.                           b.v.cmplx_val.imag*log(magnitude(&a));
  772.                     (void) Gcomplex(&result,mag*cos(ang),
  773.                         mag*sin(ang));
  774.             }
  775.             break;
  776.         case CMPLX:
  777.             switch (b.type) {
  778.                 case INTGR:
  779.                     if (a.v.cmplx_val.imag == 0.0) {
  780.                         mag = pow(a.v.cmplx_val.real,(double)abs(b.v.int_val));
  781.                         if (b.v.int_val < 0)
  782.                           if (mag != 0.0)
  783.                             mag = 1.0/mag;
  784.                           else 
  785.                             undefined = TRUE;
  786.                         (void) Gcomplex(&result,mag,0.0);
  787.                     }
  788.                     else {
  789.                         /* not so good, but...! */
  790.                         mag = pow(magnitude(&a),(double)abs(b.v.int_val));
  791.                         if (b.v.int_val < 0)
  792.                           if (mag != 0.0)
  793.                             mag = 1.0/mag;
  794.                           else 
  795.                             undefined = TRUE;
  796.                         ang = angle(&a)*b.v.int_val;
  797.                         (void) Gcomplex(&result,mag*cos(ang),
  798.                             mag*sin(ang));
  799.                     }
  800.                     break;
  801.                 case CMPLX:
  802.                     mag = pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  803.                     if (b.v.cmplx_val.real < 0.0)
  804.                       if (mag != 0.0)
  805.                         mag = 1.0/mag;
  806.                       else 
  807.                         undefined = TRUE;
  808.                     mag *= exp(-b.v.cmplx_val.imag*angle(&a));
  809.                     ang = b.v.cmplx_val.real*angle(&a) +
  810.                           b.v.cmplx_val.imag*log(magnitude(&a));
  811.                     (void) Gcomplex(&result,mag*cos(ang),
  812.                         mag*sin(ang));
  813.             }
  814.     }
  815.     push(&result);
  816. }
  817.  
  818.  
  819. f_factorial()
  820. {
  821. struct value a;
  822. register int i;
  823. register double val;
  824.  
  825.     (void) pop(&a);    /* find a! (factorial) */
  826.  
  827.     switch (a.type) {
  828.         case INTGR:
  829.             val = 1.0;
  830.             for (i = a.v.int_val; i > 1; i--)  /*fpe's should catch overflows*/
  831.                 val *= i;
  832.             break;
  833.         default:
  834.             int_error("factorial (!) argument must be an integer",
  835.             NO_CARET);
  836.         }
  837.  
  838.     push(Gcomplex(&a,val,0.0));
  839.             
  840. }
  841.  
  842.  
  843. int
  844. f_jump(x)
  845. union argument *x;
  846. {
  847.     return(x->j_arg);
  848. }
  849.  
  850.  
  851. int
  852. f_jumpz(x)
  853. union argument *x;
  854. {
  855. struct value a;
  856.     int_check(&top_of_stack);
  857.     if (top_of_stack.v.int_val) {    /* non-zero */
  858.         (void) pop(&a);
  859.         return 1;                /* no jump */
  860.     }
  861.     else
  862.         return(x->j_arg);        /* leave the argument on TOS */
  863. }
  864.  
  865.  
  866. int
  867. f_jumpnz(x)
  868. union argument *x;
  869. {
  870. struct value a;
  871.     int_check(&top_of_stack);
  872.     if (top_of_stack.v.int_val)    /* non-zero */
  873.         return(x->j_arg);        /* leave the argument on TOS */
  874.     else {
  875.         (void) pop(&a);
  876.         return 1;                /* no jump */
  877.     }
  878. }
  879.  
  880.  
  881. int
  882. f_jtern(x)
  883. union argument *x;
  884. {
  885. struct value a;
  886.  
  887.     int_check(pop(&a));
  888.     if (a.v.int_val)
  889.         return(1);                /* no jump; fall through to TRUE code */
  890.     else
  891.         return(x->j_arg);        /* go jump to FALSE code */
  892. }
  893.